package utils

import (
	"fmt"
	"github.com/pquerna/otp/totp"
	qr "github.com/skip2/go-qrcode"
	"strings"
)

// 生成 TOTP 密钥和二维码
func generateTOTPSecret(user, issuer string) (string, string, error) {
	// 生成密钥（基于 TOTP 标准）
	key, err := totp.Generate(totp.GenerateOpts{
		Issuer:      issuer, // 应用名称（如 "MyApp"）
		AccountName: user,   // 用户名（如 "user@example.com"）
		SecretSize:  16,     // 密钥长度（16 字节 = 128 位，推荐值）
	})
	if err != nil {
		return "", "", err
	}

	// 密钥（客户端需存储，用于生成验证码）
	secret := key.Secret()

	// 生成二维码 URL（供客户端扫描）
	qrURL := key.URL()

	return secret, qrURL, nil
}

// 保存二维码为图片文件
func saveQRCode(qrURL, filename string) error {
	// 使用 go-qrcode 库生成 QR 码图片
	err := qr.WriteFile(qrURL, qr.Medium, 256, filename)
	if err != nil {
		return err
	}
	return nil
}

func MfaCreate(user, issuer string) {
	secret, qrURL, err := generateTOTPSecret(user, issuer)
	if err != nil {
		fmt.Printf("生成密钥失败: %v\n", err)
		return
	}

	// 保存二维码（用户用 Authenticator 扫描）
	err = saveQRCode(qrURL, "mfa_qr.png")
	if err != nil {
		fmt.Printf("保存二维码失败: %v\n", err)
		return
	}

	fmt.Printf("用户 %s 的 MFA 密钥: %s\n", user, secret)
	fmt.Println("二维码已保存为 mfa_qr.png，请用 Google Authenticator 扫描")
}

// MFAVerify 验证MFA验证码
// 安全性注意事项
// 1.密钥存储：用户的 MFA 密钥必须加密存储（如使用 AES 加密后存入数据库），避免明文泄露。
// 2.二维码展示：生成的二维码仅在用户开启 MFA 时展示一次，之后不可再次查看（需重置 MFA 时重新生成）。
// 3.备用验证码：为用户生成一批备用验证码（如 10 个一次性代码），供用户在无法使用 Authenticator 时使用（需单向哈希存储，防止泄露）。
// 4.算法选择：默认使用 SHA1，如需更高安全性，可指定 Algorithm: otp.AlgorithmSHA256（需客户端支持）。
func MFAVerify(secret, code string) bool {
	secret = strings.TrimSpace(secret)
	code = strings.TrimSpace(code)
	if secret == "" || code == "" {
		return false
	}
	// 允许 1 个时间窗口误差（每个窗口 30 秒，即允许 ±30 秒的时间偏差）
	valid := totp.Validate(code, secret)
	/*
		// 自定 义时间窗口（允许 ±60 秒偏差）
		valid := totp.ValidateCustom(code, secret, time.Now(), totp.ValidateOpts{
			Period:    30,   // 验证码有效期（秒）
			Skew:      2,    // 允许的时间窗口偏差（2 = ±60 秒）
			Digits:    6,    // 验证码位数（6 位，标准值）
			Algorithm: otp.AlgorithmSHA1, // 哈希算法（SHA1 是标准，也可使用 SHA256）
		})
	*/
	return valid
}
